package resources

import (
	"cloud_android_backend/pkg/models/orders"
	"github.com/jinzhu/gorm"
	"time"
)

//CREATE TABLE `instance_uses` (
//  `id` int NOT NULL AUTO_INCREMENT,
//  `user_id` bigint DEFAULT NULL,
//  `instance_id` bigint DEFAULT NULL,
//  `start_time` datetime DEFAULT NULL,
//  `expire_time` datetime DEFAULT NULL,
//  `status` tinyint(1) DEFAULT NULL COMMENT '0 过期 1使用中',
//  `created_at` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
//  `updated_at` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
//`image` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL,
//  `image_tag` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL,
//  `auto_renew` tinyint(1) DEFAULT NULL COMMENT '0否 1是',
// `actual_start_time` datetime DEFAULT NULL,
// `is_renew` tinyint(1) DEFAULT NULL COMMENT '0否 1是',
// `state` tinyint(1) DEFAULT NULL COMMENT '0启动中 1在线 2离线',
//`operate_time` datetime DEFAULT NULL,
//`is_trial` tinyint NOT NULL,
//  PRIMARY KEY (`id`)
//) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;

type InstanceUses struct {
	Id              int64         `json:"id" gorm:"primary_key;column:id"`
	UserId          string        `json:"user_id" gorm:"column:user_id"`
	InstanceId      int64         `json:"instance_id" gorm:"column:instance_id"`
	StartTime       time.Time     `json:"start_time" gorm:"column:start_time"`
	ExpireTime      time.Time     `json:"expire_time" gorm:"column:expire_time"`
	Status          int           `json:"status" gorm:"column:status"`
	CreatedAt       time.Time     `json:"created_at" gorm:"column:created_at"`
	UpdatedAt       time.Time     `json:"updated_at" gorm:"column:updated_at"`
	OrderId         int64         `json:"order_id" gorm:"column:order_id"`
	Image           string        `json:"image" gorm:"column:image"`
	ImageTag        string        `json:"image_tag" gorm:"column:image_tag"`
	AutoRenew       int           `json:"auto_renew" gorm:"column:auto_renew"`
	ScreenShot      string        `json:"screen_shot" gorm:"column:screen_shot"`
	InstanceName    string        `json:"instance_name" gorm:"column:instance_name"`
	Instances       Instances     `json:"instances" gorm:"foreignkey:InstanceId"`
	Orders          orders.Orders `json:"orders" gorm:"foreignkey:OrderId"`
	ActualStartTime time.Time     `json:"actual_start_time" gorm:"column:actual_start_time"`
	IsRenew         int           `json:"is_renew" gorm:"column:is_renew"`
	PrewInstanceId  int64         `json:"prew_instance_id" gorm:"column:prew_instance_id"`
	State           int           `json:"state" gorm:"column:state"`
	OperateTime     time.Time     `json:"operate_time" gorm:"column:operate_time"`
	IsTrial         int           `json:"is_trial" gorm:"column:is_trial"`
	ProxyId         int           `json:"proxy_id" gorm:"column:proxy_id"`
}

type InstanceUseStatus int
type InstanceUseState int

const (
	InstanceUseStatusPending InstanceUseStatus = 0
	InstanceUseStatusUsing   InstanceUseStatus = 1
	InstanceUseStatusExpired InstanceUseStatus = 2
)
const (
	InstanceUseStatePending InstanceUseState = 0
	InstanceUseStateOnline  InstanceUseState = 1
	InstanceUseStateOffline InstanceUseState = 2
)

func (i *InstanceUses) TableName() string {
	return "instance_uses"
}

func (i *InstanceUses) Create(db *gorm.DB) error {
	return db.Table(i.TableName()).Create(i).Error
}

func (i *InstanceUses) Update(db *gorm.DB) error {
	return db.Model(i).Where("id = ?", i.Id).Update(i).Error
}
func (i *InstanceUses) UpdatePartFields(db *gorm.DB, fields map[string]interface{}) error {
	return db.Table(i.TableName()).Where("id = ?", i.Id).Update(fields).Error
}
func (i *InstanceUses) GetById(db *gorm.DB) error {
	return db.Table(i.TableName()).Where("id = ?", i.Id).First(i).Error
}
func (i *InstanceUses) GetByIdWithInstanceInfo(db *gorm.DB) error {
	return db.Table(i.TableName()).Preload("Instances").Preload("Instances.Machine").Where("id = ?", i.Id).First(i).Error
}
func (i *InstanceUses) GetUsingByInstanceId(db *gorm.DB) error {
	return db.Table(i.TableName()).Where("instance_id = ?", i.InstanceId).Where("status = ?", InstanceUseStatusUsing).First(i).Error
}
func (i *InstanceUses) GetUsingList(db *gorm.DB) ([]InstanceUses, error) {
	var list []InstanceUses
	err := db.Where("status = ?", int(InstanceUseStatusUsing)).Preload("Instances").Find(&list).Error
	return list, err
}
func (i *InstanceUses) GetByOrderId(db *gorm.DB) error {
	return db.Table(i.TableName()).Where("order_id = ?", i.OrderId).First(i).Error
}
func (i *InstanceUses) GetByOrderIdWithInstance(db *gorm.DB) error {
	return db.Preload("Instances").Preload("Instances.Machine").Where("order_id = ?", i.OrderId).First(i).Error
}
func (i *InstanceUses) GetListByIds(db *gorm.DB, ids []int64) ([]InstanceUses, error) {
	var instanceUses []InstanceUses
	err := db.Preload("Instances").Preload("Instances.Machine").Where("id in (?)", ids).Find(&instanceUses).Error
	return instanceUses, err
}
func (i *InstanceUses) GetListByOrderId(db *gorm.DB) ([]InstanceUses, error) {
	var instanceUses []InstanceUses
	err := db.Preload("Instances").Where("order_id = ?", i.OrderId).Find(&instanceUses).Error
	return instanceUses, err
}

func (i *InstanceUses) GetListByUserId(db *gorm.DB) ([]InstanceUses, error) {
	var instanceUses []InstanceUses
	err := db.Preload("Instances").Preload("Instances.Machine").Where("user_id = ?", i.UserId).Where("status in (?)", []int{int(InstanceUseStatusUsing)}).Find(&instanceUses).Error
	return instanceUses, err
}

func (i *InstanceUses) GetUsingButExpiredInstances(db *gorm.DB) ([]InstanceUses, error) {
	var instanceUses []InstanceUses
	err := db.Preload("Instances").Where("status = ?", int(InstanceUseStatusUsing)).Where("expire_time < ?", time.Now()).Find(&instanceUses).Error
	return instanceUses, err
}

type InstanceUsesWithInstanceInfo struct {
	InstanceUses
}

func (i *InstanceUses) GetInstanceInfoByUdid(db *gorm.DB, adb_port string, ip string) (InstanceUsesWithInstanceInfo, error) {
	var instanceUsesWithInstanceInfo InstanceUsesWithInstanceInfo
	return instanceUsesWithInstanceInfo, db.Table(i.TableName()).Select("instance_uses.*").Joins("join instances on instances.id = instance_uses.instance_id").
		Joins("join machines on machines.id = instances.machine_id").
		Where("instances.adb_port = ?", adb_port).
		Where("machines.ip = ?", ip).First(&instanceUsesWithInstanceInfo).Error
}

func (i *InstanceUses) GetBindProxyInstanceListByUserId(db *gorm.DB, proxy_id int) ([]InstanceUses, error) {
	var instanceUses []InstanceUses
	err := db.Where("user_id = ?", i.UserId).Where("proxy_id = ?", proxy_id).Where("status=?", int(InstanceUseStatusUsing)).Find(&instanceUses).Error
	return instanceUses, err
}
